const fs = require('fs');
class DefaultMap extends Map {
    constructor(defaultValue) {
        super();
        this.defaultValue = defaultValue;
    }
    get(key) {
        if (super.has(key)) {
            return super.get(key);
        }
        return this.defaultValue;
    }
};

class Histogram {
    constructor() {
        this.letterCounts = new DefaultMap(0);
        this.totalCounts = 0;
    }

    addText (text) {
        let count = this.letterCounts.get(text);
        this.letterCounts.set(text, count + 1);
        this.totalCounts ++;
    }

    toString() {
        let entries = [...this.letterCounts.keys()];
        const lines = entries.sort((a,b) => this.letterCounts.get(b) - this.letterCounts.get(a)).map((code) => {
            const p = this.letterCounts.get(code) *100 / this.totalCounts;
            if (p < 1) {
                return null;
            }
            return `${code}: ${'#'.repeat(Math.round(p))} ${p.toFixed(2)}%`;
        })
        return lines.filter((code) => Boolean(code)).join('\n');
    }
}

async function histogramFromStdin () {

    let histogram = new Histogram();
    const file = await fs.readFileSync('./2024.11.24.js', { encoding: 'utf8' });
    for (let _chunk of file) {
        const chunk = _chunk.replaceAll(' ', '').replaceAll('\n','').replaceAll('\r', '');
        if (chunk) {
            histogram.addText(chunk.toUpperCase?.());
        }
    }
    return histogram
}

histogramFromStdin().then((histogram) => {
    // console.log(histogram.totalCounts, '\n\n');
    // console.log(histogram.letterCounts, '\n\n');
    console.log(histogram.toString());
}).catch(error => {
    console.log(error)
})
